package dk.modified.radioonlineapp;

import java.lang.ref.WeakReference;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.ImageView;
import android.widget.TextView;

public class RadioAdapter extends ArrayAdapter<Radio> {

	Context context;
	int layoutResourceId;
	NoFilter noFilter;
	List<Radio> data;
	CommentsDataSource datasource;
	Bitmap def;
	FileManager fm;

	public RadioAdapter(Context context, int layoutResourceId, List<Radio> data) {
		super(context, layoutResourceId, data);
		this.layoutResourceId = layoutResourceId;
		this.context = context;
		this.data = data;
		def = BitmapFactory.decodeResource(context.getResources(),
				R.raw.default_image);
		fm = new FileManager(context);
	}

	// Loads a bitmap into an ImageView by giving the location to fetch it from
	// by using the filename "slug"
	// if "download" is true, it will begin downloading an image, using an
	// AsyncTask.
	public void loadBitmap(ImageView imageView, String slug, boolean download) {
		if (cancelPotentialWork(slug, imageView)) {
			// final AsyncDrawable asyncDrawable = new AsyncDrawable(
			// context.getResources(), def, task);

			if (fm.fileExistance(slug)) {
				imageView.setImageBitmap(fm.LoadBitmapInternalStorage(slug));
			} else {
				if (!download) {
					if (MainActivity.tabHost.getCurrentTab() == 3) {
						slug = slug.toLowerCase();
						int id = context.getResources().getIdentifier(slug,
								"drawable", context.getPackageName());

						imageView.setImageResource(id);

					} else {
						imageView.setImageResource(R.raw.default_image);
					}
				} else {
					final BitmapWorkerTask task = new BitmapWorkerTask(
							imageView);
					task.execute(slug);
				}
				// imageView.setImageDrawable(asyncDrawable);
				// task.execute(slug);
			}
		}
	}

	// Checks if the same task is already running, and cancels the already
	// running task, if so.
	public static boolean cancelPotentialWork(String slug, ImageView imageView) {
		final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);

		if (bitmapWorkerTask != null) {
			final String bitmapData = bitmapWorkerTask.slug;
			if (bitmapData != slug) {
				// Cancel previous task
				bitmapWorkerTask.cancel(true);
			} else {
				// The same work is already in progress
				return false;
			}
		}
		// No task associated with the ImageView, or an existing task was
		// cancelled
		return true;
	}

	// Takes an imageView and returns a BitmapWorkerTask if the imageView
	// drawable is an instance of AsyncDrawable
	private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
		if (imageView != null) {
			final Drawable drawable = imageView.getDrawable();
			if (drawable instanceof AsyncDrawable) {
				final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
				return asyncDrawable.getBitmapWorkerTask();
			}
		}
		return null;
	}

	
	// Fills the listview rows it also performs checks whether an image is already available on the UI or it should be downloaded.
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		View row = convertView;
		RadioHolder holder = null;
		datasource = new CommentsDataSource(context);
		if (row == null) {
			LayoutInflater inflater = ((Activity) context).getLayoutInflater();
			row = inflater.inflate(layoutResourceId, parent, false);
			holder = new RadioHolder();
			holder.itemRowImg = (ImageView) row.findViewById(R.id.itemRowImg);
			holder.itemRowText = (TextView) row.findViewById(R.id.itemRowText);
			holder.itemRowButton = (ImageView) row
					.findViewById(R.id.itemRowButton);
			holder.position = position;

			row.setTag(holder);
		} else {
			holder = (RadioHolder) row.getTag();
		}

		Radio radio = data.get(position);
		String slug = radio.getSlug();
		datasource.Open();
		if (datasource.DoesFavExists(radio.getId())) {
			holder.itemRowButton.setBackgroundResource(R.raw.fav_yes);
		} else {
			holder.itemRowButton.setBackgroundResource(R.raw.fav_no);
		}
		datasource.Close();

		if (MainActivity.tabHost.getCurrentTab() == 3) {
			holder.itemRowText.setText(radio.getName());
			loadBitmap(holder.itemRowImg, radio.getCountry(), false);
		} else {
			holder.itemRowText.setText(radio.getName());
			loadBitmap(holder.itemRowImg, slug, false);
		}

		holder.itemRowButton.setId(radio.getId());
		holder.itemRowButton.setTag(radio);
		holder.itemRowButton.setTag(41742839, holder.itemRowImg);
		holder.itemRowButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Radio ra = (Radio) v.getTag();
				ImageView image = (ImageView) v.getTag(41742839);
				loadBitmap(image, ra.getSlug(), true);

				datasource.Open();
				if (datasource.DoesFavExists(v.getId())) {
					datasource.RemoveFromFav(v.getId());
					v.setBackgroundResource(R.raw.fav_no);

					if (MainActivity.tabHost.getCurrentTab() == 2) {
						MainActivity.listRaFav.clear();
						try {
							MainActivity.listRaFav.addAll(datasource
									.SelectFavRadiosFromDB());
							datasource.Close();
							notifyDataSetChanged();
						} catch (Exception e) {
							datasource.Close();
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}

				} else {

					try {
						datasource.InsertToFav(ra);
						v.setBackgroundResource(R.raw.fav_yes);

					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				datasource.Close();
			}
		});

		return row;
	}

	// class used to keep a reference of rows in the getView() method
	public static class RadioHolder {
		ImageView itemRowImg;
		TextView itemRowText;
		ImageView itemRowButton;
		int position;
	}

	
	class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
		private final WeakReference<ImageView> imageViewReference;
		private String slug = null;

		public BitmapWorkerTask(ImageView imageView) {
			// Use a WeakReference to ensure the ImageView can be garbage
			// collected
			imageViewReference = new WeakReference<ImageView>(imageView);
		}

		// Download image in background
		@Override
		protected Bitmap doInBackground(String... params) {
			slug = params[0];
			String url = "http://cdn002.itunedradio.com/img/logos/" + slug
					+ ".png";

			Bitmap img = ByteConverter.getBitmapFromURL(url, def);

			if (img != null)
				fm.SaveBitmapInternalStorage(img, slug);
			return img;
		}

		// Once complete, see if ImageView is still around and set bitmap.
		@Override
		protected void onPostExecute(Bitmap bitmap) {
			if (isCancelled()) {
				bitmap = null;
			}

			if (imageViewReference != null && bitmap != null) {
				final ImageView imageView = imageViewReference.get();
				final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
				if (this == bitmapWorkerTask && imageView != null) {
					imageView.setImageBitmap(bitmap);
				}
			}
			notifyDataSetChanged();
		}
	}

	static class AsyncDrawable extends BitmapDrawable {
		private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;

		public AsyncDrawable(Resources res, Bitmap bitmap,
				BitmapWorkerTask bitmapWorkerTask) {
			super(res, bitmap);
			bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(
					bitmapWorkerTask);
		}

		public BitmapWorkerTask getBitmapWorkerTask() {
			return bitmapWorkerTaskReference.get();
		}
	}

	/**
	 * Override ArrayAdapter.getFilter() to return our own filtering.
	 */
	public Filter getFilter() {
		if (noFilter == null) {
			noFilter = new NoFilter();
		}
		return noFilter;
	}

	/**
	 * Class which does not perform any filtering. Filtering is already done by
	 * the web service when asking for the list, so there is no need to do any
	 * more as well. This way, ArrayAdapter.mOriginalValues is not used when
	 * calling e.g. ArrayAdapter.add(), but instead ArrayAdapter.mObjects is
	 * updated directly and methods like getCount() return the expected result.
	 */
	private class NoFilter extends Filter {
		protected FilterResults performFiltering(CharSequence prefix) {
			return new FilterResults();
		}

		protected void publishResults(CharSequence constraint,
				FilterResults results) {
		}
	}
}
